# @Time : 2025-01-08 14:45
# @Author : Fioman 
# @Phone : 13149920693
"""
异常处理,关于异常处理的模块,所有的异常最终都是在这里去处理
"""
import os
import sys
from ctypes import windll
from enum import Enum
from functools import wraps
from typing import Callable, get_type_hints

import gevent

import app_config
from common.produce_logger import debug_produce
from eap_tool.eap_logger import debug_eap
from personal_tool.data_result import DataResult


# 装饰器函数,用来处理异常,根据有无注解返回值DataResult来进内部的返回值的处理
# 1) 打印异常信息
class ModuleType(Enum):
    EAP = "eap"
    PRODUCE = "produce"

# 异常处理装饰器,如果出现了异常,直接就在这里打印了,不用在调用那里去打印了,调用那里只管后续的处理
def error_handler(module_type: ModuleType = ModuleType.EAP):
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                res = func(*args, **kwargs)
                if res is DataResult:
                    if module_type == ModuleType.EAP:
                        debug_eap(res.info)
                    elif module_type == ModuleType.PRODUCE:
                        debug_produce(res.info)
                return res
            except Exception as e:
                excType, excValue, excTraceback = sys.exc_info()
                tb = excTraceback
                tb = tb.tb_next

                errorDetails = {
                    'function': func.__name__,
                    'filename': os.path.basename(tb.tb_frame.f_code.co_filename),
                    'fullPath': tb.tb_frame.f_code.co_filename,
                    'lineNo': tb.tb_lineno,
                    'error': str(e)
                }

                errorInfo = (
                    f"Error in {errorDetails['function']}(),{errorDetails['error']}\n"
                    f"File path: {errorDetails['fullPath']}\n"
                    f"Function: {errorDetails['function']}\n"
                    f"Line number: {errorDetails['lineNo']}\n"
                )

                if module_type == ModuleType.EAP:
                    debug_eap(errorInfo)
                elif module_type == ModuleType.PRODUCE:
                    debug_produce(errorInfo)
                returnType = get_type_hints(func).get("return")
                if returnType is DataResult:
                    result = DataResult()
                    result.state = False
                    result.info = errorInfo
                    return result
                if returnType is bool:
                    return False

        return wrapper

    return decorator


def error_handler_eap(func: Callable) -> Callable:
    return error_handler()(func)


def error_handler_produce(func: Callable) -> Callable:
    return error_handler(ModuleType.PRODUCE)(func)


def show_error_info(errorInfo: str, title: str = "程序启动错误提示"):
    """
    python 后台显示异常,处理web还未启动的时候的异常弹窗
    :param title:
    :param errorInfo:
    :return:
    """
    debug_produce(f"{title}: {errorInfo}")
    windll.user32.MessageBoxW(0, f"{title}: {errorInfo}", "错误", 0x00000010)
    gevent.sleep(1)
    app_config.isWorkStop = True
    app_config.isMainAlive = False
    sys.exit(0)


@error_handler_eap
def func_test(a, b) -> DataResult:
    result = DataResult()
    c = a / b
    result.state = True
    return result


@error_handler_produce
def func_test2(a, b):
    return a / b


if __name__ == '__main__':
    res = func_test(1, 0)
    print(res.state)
    res = func_test2(1, 0)
    if res is DataResult:
        print(res.state)
    else:
        print(res)
